#include "sdl_graphic.h"

namespace sdl_graphic {
/*
 * struct mesh::matmap
 */
/*
mesh::matmap::matmap(
                const int & off,
                const sdl_ptr<vertex_vmap> & vmap,
                const sdl_ptr<vertex_vmap> & nmap,
                const sdl_ptr<color_vmap> & cmap,
                const std::vector<sdl_ptr<tex_vmap> > &tmap,
                const sdl_ptr<material> & m):
                        offset(off),
                        mat(m),
                        vertices(vmap),
                        normals(nmap),
                        colors(cmap),
                        texcoords(tmap)
        {
                _msg("matmap",2,"tworzenie mapy materiałowej z "<<vertices->map->size()<<" wierzchołków i "<<texcoords.size()<<" map teksturowych");

                if (tmap.size()==0)
                        _msg("matmap",40,"podana lista współrzędnych tekstur jest pusta!");

                if (!m)
                        _msg("matmap",40,"podany wskaźnik do materiału jest pusty!");

                if (tmap.size()!=m->textures.size())
                        _msg("matmap",40,"liczba map współrzędnych nie zgadza się z liczbą tekstur w materiale!");
        }

mesh::matmap::~matmap() {
        texcoords.clear();
}
 */

/*
 * class mesh
 */

mesh::mesh(const std::string & name) :
sdl_prim(name),
radius(0.0f)
{
    _msg("mesh", 6, "tworzenie pustej siatki " << name);
}

mesh::~mesh()
{
    _msg("mesh", 5, "kasowanie siatki " << name());
    matmaps.clear();
    texcoords.clear();
}

void mesh::create(const sdl_ptr<mvector3fmap> & vmap, const sdl_ptr<mvector3fmap> & nmap, const sdl_ptr<mvector4fmap> & cmap, const std::vector<sdl_ptr<mvector2fmap> > & tmap, const sdl_ptr<indexmap> & idx)
{
    _msg("mesh", 6, "tworzenie siatki " << name() << " z podanych map wektorowych o " << vmap->size() << " wierzchołkach i " << tmap.size() << " mapach tekstury");
    vertices = sdl_ptr<vertex_vmap > (new vertex_vmap(vmap));
    normals = sdl_ptr<normal_vmap > (new normal_vmap(nmap));
    colors = sdl_ptr<color_vmap > (new color_vmap(cmap));
    indices = idx;

    for (int i = 0; i < tmap.size(); i++)
        texcoords.push_back(new tex_vmap(tmap[i]));

    if (!vmap)
        _msg("mesh", 40, name() << ": ostrzeżenie: wskaźnik do wierzchołków jest pusty!");

    if (!nmap)
        _msg("mesh", 40, name() << ": ostrzeżenie: wskaźnik do normali jest pusty!");

    if (!cmap)
        _msg("mesh", 40, name() << ": ostrzeżenie: wskaźnik do kolorów jest pusty!");

    if (tmap.size() == 0)
        _msg("mesh", 40, name() << ": ostrzeżenie: nie ma żadnych map tekstury!");

    // obliczenie promienia siatki (bounding sphere)
    mvector3f origin(0.0f, 0.0f, 0.0f);
    for (int i = 0; i < vmap->size(); i++) {
        float d = origin.distance((*vmap)[i]);
        if (d > radius)
            radius = d;
    }
    _msg("mesh", 3, "siatka " << name() << " ma promień " << radius);
}

/*
void mesh::v_subst(const sdl_ptr<mvector3fmap> & vmap) {
        if (!vmap)
                _msg("mesh",40,name()<<": ostrzeżenie: wskaźnik do wierzchołków jest pusty!");

        vertices=sdl_ptr<vertex_vmap>(new vertex_vmap(vmap));
}

void mesh::c_subst(const sdl_ptr<mvector4fmap> & cmap) {
        if (!cmap)
                _msg("mesh",40,name()<<": ostrzeżenie: wskaźnik do kolorów jest pusty!");

        colors=sdl_ptr<color_vmap>(new color_vmap(cmap));
}

void mesh::n_subst(const sdl_ptr<mvector3fmap> & nmap) {
        if (!nmap)
                _msg("mesh",40,name()<<": ostrzeżenie: wskaźnik do normali jest pusty!");

        normals=sdl_ptr<normal_vmap>(new normal_vmap(nmap));
}

void mesh::t_subst(const std::vector<sdl_ptr<mvector2fmap> > &tmap) {
        if (tmap.size())
                _msg("mesh",40,name()<<": ostrzeżenie: podana lista współrzędnych tekstur jest pusta");

        texcoords.clear();

        for (int i=0;i<tmap.size();i++)
                texcoords.push_back(new tex_vmap(tmap[i]));
}

sdl_ptr<vertex_vmap> mesh::get_vertices() {
        return vertices;
}

sdl_ptr<normal_vmap> mesh::get_normals() {
        return normals;
}

sdl_ptr<color_vmap> mesh::get_colors() {
        return colors;
}

std::vector<sdl_ptr<tex_vmap> >  mesh::get_texcoords() {
        return texcoords;
}
 */
float mesh::get_radius()
{
    return radius;
}

void mesh::set_material(const sdl_ptr<material> & mat)
{
    if (!mat) {
        _msg("mesh", 40, name() << ": ostrzeżenie: wskaźnik do materiału jest pusty!");
    } else {
        if (mat->textures.size() == 0)
            _msg("mesh", 40, name() << ": ostrzeżenie: podany materiał nie zawiera żadnych tekstur!");

        if (mat->textures.size() != texcoords.size())
            _msg("mesh", 40, name() << ": ostrzeżenie: liczba tekstur " << mat->textures.size() << " w materiale nie zgadza się z ilością map współrzędnych tekstur " << texcoords.size());
    }
    if (mat) {
        _msg("mesh", 4, "ustawianie materiału " << mat->name() << " dla " << name());
    } else
        _msg("mesh", 4, "nie ustawiam żadnego materiału dla " << name());

    matmaps.clear();
    matmaps.push_back(matmap(0, indices->size(), indices->size(), mat));
}

};
